package com.nickstumpos.android.GmailWidgetPlus.gmailProvider;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import com.nickstumpos.android.GmailWidgetPlus.Constants.GMWP_Constants;
import com.nickstumpos.android.GmailWidgetPlus.gmailObserver.GmailObserver;
import com.nickstumpos.android.GmailWidgetPlus.gmailObserver.IObserveChangeListener;
import com.nickstumpos.android.GmailWidgetPlus.labels.LabelBlackListManager;
import com.nickstumpos.android.GmailWidgetPlus.labels.LabelCountPair;
import com.nickstumpos.android.GmailWidgetPlus.labels.SystemLabels;

public class GmailProvider implements IObserveChangeListener {

	public static Intent getGmailAvailable(final Context context) {

		final PackageManager packageManager = context.getPackageManager();
		Intent i = packageManager.getLaunchIntentForPackage(GMWP_Constants.GMAIL_PKG);
		if (i == null) {
			i = new Intent().setClassName(GMWP_Constants.GMAIL_PKG,
					GMWP_Constants.GMAIL_CLASS_DEFLT);
		}
		Log.i("GMWP", "Using intent: " + i.toString());
		return i;
	}

	private String					account;
	private final ContentResolver	contentResolver;
	private boolean					showall		= false;
	private int						totalUnread	= 0;
	private GmailObserver			go			= null;
	private final Context			context;

	private final String			updateAction;

	public GmailProvider(final Context context,
			final String account,
			final boolean showAll,
			final String updateAction) {

		super();
		this.updateAction = updateAction;
		this.context = context;
		this.account = account;
		if (this.account == null) {
			final Account[] accounts = AccountManager.get(context)
					.getAccountsByType(GMWP_Constants.GOOGLE_ACCOUNT_TYPE);
			if ((accounts != null) && (accounts.length > 0)
					&& (accounts[0] != null)) {
				this.account = accounts[0].name;
			} else {
				this.account = null;
			}
		}
		this.contentResolver = context.getContentResolver();
		this.showall = showAll;
	}

	public String getAccount() {

		return this.account;
	}

	public List<LabelCountPair> getLabelsAndCounts(final int widgetId) {
		if (!LabelBlackListManager.isInit(widgetId)) {
			LabelBlackListManager.initBlacklist(this.context, widgetId);
		}
		this.totalUnread = 0;
		int totalCount = 0;
		final List<LabelCountPair> ret = new ArrayList<LabelCountPair>();
		final Cursor labels = this.contentResolver.query(Uri.parse(GMWP_Constants.GMAIL_LABEL_PRV + this.account),
				null,
				null,
				null,
				null);
		if ((labels != null) && labels.moveToFirst()) {
			do {
				if ("^all".equals(labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS))) {
					this.totalUnread = labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS);
				}
				final String labelName = labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS);

				if (!LabelBlackListManager.isBlacklisted(labelName, widgetId) && (!labelName.startsWith(GMWP_Constants.SYSTEM_LABEL_PREFIX) || (SystemLabels.systemLabelByCode(labelName) != null))) {
					if (this.showall) {
						ret.add(new LabelCountPair(labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS),
								labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS)));
						totalCount += labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS);
					} else {
						if (labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS) > 0) {
							ret.add(new LabelCountPair(labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS),
									labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS)));
							totalCount += labels.getInt(GMWP_Constants.LABEL_QRY_UNREAD_POS);
						}
					}
				}
			} while (labels.moveToNext());
			labels.close();
		}
		if (totalCount < this.totalUnread) {
			this.totalUnread = totalCount;
		}
		return ret;
	}

	public List<String> getLabelsNames() {

		final List<String> ret = new ArrayList<String>();
		final Cursor labels = this.contentResolver.query(Uri.parse(GMWP_Constants.GMAIL_LABEL_PRV + this.account),
				null,
				null,
				null,
				null);
		if ((labels != null) && labels.moveToFirst()) {
			do {
				final String labelName = labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS);
				if (!labelName.startsWith(GMWP_Constants.SYSTEM_LABEL_PREFIX) || (SystemLabels.systemLabelByCode(labelName) != null)) {
					ret.add(labels.getString(GMWP_Constants.LABEL_QRY_NAME_POS));
				}
			} while (labels.moveToNext());
			labels.close();
		}
		return ret;
	}

	public int getTotalUnread() {

		return this.totalUnread;
	}

	public boolean haveAccount() {

		if (this.account == null) {
			return false;
		}
		return true;
	}

	@Override
	public void onChange() {

		if (this.updateAction != null) {
			try {
				PendingIntent.getBroadcast(this.context,
						(int) Calendar.getInstance().getTimeInMillis() << 4,
						new Intent() {

							{
								this.setAction(GmailProvider.this.updateAction);
								this.putExtra(GMWP_Constants.EXTRA_WIDGET_ACTION,
										GMWP_Constants.WIDGET_GMAIL_UPDATE);
							}
						},
						0)
						.send();
			} catch (final CanceledException e) {
				Log.e("GMWP", e.getMessage(), e);
			}
		}
	}

	public void refresh(final int widgetId) {

		final SharedPreferences prefs = this.context.getSharedPreferences(GMWP_Constants.GMW_PREFS_REF,
				0);
		this.account = prefs.getString(GMWP_Constants.PREF_ACCOUNT_REF + String.valueOf(widgetId),
				this.account);
		this.showall = prefs.getBoolean(GMWP_Constants.PREF_SHOWALL_REF + String.valueOf(widgetId),
				false);
	}

	public void registerObserver() {

		if (this.go == null) {
			this.go = new GmailObserver(new Handler());
			this.go.setListener(this);
			this.contentResolver.registerContentObserver(Uri.parse(GMWP_Constants.GMAIL_BASE_PRV),
					true,
					this.go);
		}
	}

	public void removeObserver() {

		if (this.go != null) {
			this.contentResolver.unregisterContentObserver(this.go);
		}
	}

	public void syncGmail() {

		final Bundle b = new Bundle();
		this.contentResolver.startSync(Uri.parse(GMWP_Constants.GMAIL_BASE_PRV),
				b);
	}
}
